/**
 * 数据映射器
 * 负责在数据库实体和DTO之间进行数据转换
 */

import type { ProductDTO, CreateProductDTO, UpdateProductDTO, CaseDTO, CreateCaseDTO, UpdateCaseDTO } from '../types/dto';
import type { products, cases } from '../db/schema';
import { nanoid } from 'nanoid';

// 产品映射器
export class ProductMapper {
  /**
   * 将数据库实体转换为DTO
   */
  static toDTO(entity: typeof products.$inferSelect): ProductDTO {
    return {
      id: entity.id,
      title: entity.title,
      name: entity.title, // 兼容旧字段名
      description: entity.description || undefined,
      content: entity.content || undefined,
      type: entity.type,
      categoryId: entity.categoryId || entity.type, // 兼容前端字段
      priceRange: entity.priceRange || (entity.priceMin && entity.priceMax ? {
        min: entity.priceMin,
        max: entity.priceMax
      } : undefined),
      priceMin: entity.priceMin,
      priceMax: entity.priceMax,
      unit: entity.unit || undefined,
      images: entity.images ? MapperUtils.safeParseJSON(entity.images, []) : [],
      features: entity.features ? MapperUtils.safeParseJSON(entity.features, undefined) : undefined,
      craftType: entity.craftType || undefined,
      // featured字段已从products表中移除
      status: entity.status as 'active' | 'inactive' | 'draft',
      sort: entity.sort,
      createdAt: entity.createdAt,
      updatedAt: entity.updatedAt
    };
  }

  /**
   * 将创建DTO转换为数据库插入对象
   */
  static fromCreateDTO(dto: CreateProductDTO): typeof products.$inferInsert {
    return {
      id: nanoid(),
      title: dto.title || dto.name, // 兼容旧字段名
      description: dto.description,
      content: dto.content || '',
      type: dto.type,
      categoryId: dto.categoryId || dto.type,
      priceRange: dto.priceRange || (dto.priceMin && dto.priceMax ? `${dto.priceMin}-${dto.priceMax}` : ''),
      priceMin: dto.priceMin,
      priceMax: dto.priceMax,
      unit: dto.unit,
      images: dto.images ? JSON.stringify(dto.images) : null,
      features: dto.features ? JSON.stringify(dto.features) : null,
      craftType: dto.craftType || '',
      // featured字段已从products表中移除
      status: dto.status ?? 'active',
      sort: dto.sort ?? 0,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
  }

  /**
   * 将更新DTO转换为数据库更新对象
   */
  static fromUpdateDTO(dto: UpdateProductDTO): Partial<typeof products.$inferInsert> {
    const updateData: Partial<typeof products.$inferInsert> = {
      updatedAt: new Date().toISOString()
    };

    if (dto.title !== undefined) updateData.title = dto.title;
    if (dto.name !== undefined) updateData.title = dto.name; // 兼容旧字段名
    if (dto.description !== undefined) updateData.description = dto.description;
    if (dto.content !== undefined) updateData.content = dto.content;
    if (dto.type !== undefined) updateData.type = dto.type;
    if (dto.categoryId !== undefined) updateData.categoryId = dto.categoryId;
    if (dto.priceRange !== undefined) updateData.priceRange = dto.priceRange;
    if (dto.priceMin !== undefined) updateData.priceMin = dto.priceMin;
    if (dto.priceMax !== undefined) updateData.priceMax = dto.priceMax;
    if (dto.unit !== undefined) updateData.unit = dto.unit;
    if (dto.images !== undefined) updateData.images = JSON.stringify(dto.images);
    if (dto.features !== undefined) updateData.features = JSON.stringify(dto.features);
    if (dto.craftType !== undefined) updateData.craftType = dto.craftType;
    // featured字段已从products表中移除
    if (dto.status !== undefined) updateData.status = dto.status;
    if (dto.sort !== undefined) updateData.sort = dto.sort;

    return updateData;
  }
}

// 案例映射器
export class CaseMapper {
  /**
   * 将数据库实体转换为DTO
   */
  static toDTO(entity: typeof cases.$inferSelect, tagsInfo: any[] = [], categoryInfo?: any): any {
    return {
      id: entity.id,
      title: entity.title,
      description: entity.description || undefined,
      industry: entity.industry || undefined,
      categoryId: entity.categoryId,
      category: categoryInfo?.name || entity.categoryId, // 使用分类名称，如果没有则使用ID
      client: entity.clientName || '', // 映射到clientName
      clientName: entity.clientName || '',
      duration: entity.duration || undefined,
      completedAt: entity.completedAt || undefined,
      location: entity.location || undefined,
      content: entity.content || undefined,
      images: entity.images ? MapperUtils.safeParseJSON(entity.images, []) : [],
      services: entity.services ? MapperUtils.safeParseJSON(entity.services, []) : [],
      tags: tagsInfo.length > 0 ? tagsInfo : [],
      challenges: entity.challenges || undefined,
      solutions: entity.solutions || undefined,
      technologies: entity.technologies ? MapperUtils.safeParseJSON(entity.technologies, []) : [],
      highlights: entity.highlights || undefined,
      projectValue: entity.projectValue || undefined,
      // featured字段已从cases表中移除
      status: entity.status as 'active' | 'inactive' | 'draft',
      sort: entity.sort,
      createdAt: entity.createdAt,
      updatedAt: entity.updatedAt
    };
  }

  /**
   * 将创建DTO转换为数据库插入对象
   */
  static fromCreateDTO(dto: any): typeof cases.$inferInsert {
    return {
      id: nanoid(),
      title: dto.title,
      categoryId: dto.categoryId,
      industry: dto.industry,
      description: dto.description,
      content: dto.content,
      duration: dto.duration,
      services: dto.services ? JSON.stringify(dto.services) : null,
      images: dto.images ? JSON.stringify(dto.images) : null,
      highlights: dto.highlights,
      technologies: dto.technologies ? JSON.stringify(dto.technologies) : null,
      // tags字段已移除，使用services字段存储标签信息
      clientName: dto.clientName,
      completedAt: dto.completedAt,
      location: dto.location,
      projectValue: dto.projectValue,
      challenges: dto.challenges,
      solutions: dto.solutions,
      // featured字段已从cases表中移除
      status: dto.status ?? 'active',
      sort: dto.sort ?? 0,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
  }

  /**
   * 将更新DTO转换为数据库更新对象
   */
  static fromUpdateDTO(dto: any): Partial<typeof cases.$inferInsert> {
    const updateData: Partial<typeof cases.$inferInsert> = {
      updatedAt: new Date().toISOString()
    };

    if (dto.title !== undefined) updateData.title = dto.title;
    if (dto.categoryId !== undefined) updateData.categoryId = dto.categoryId;
    if (dto.industry !== undefined) updateData.industry = dto.industry;
    if (dto.description !== undefined) updateData.description = dto.description;
    if (dto.content !== undefined) updateData.content = dto.content;
    if (dto.duration !== undefined) updateData.duration = dto.duration;
    if (dto.services !== undefined) updateData.services = JSON.stringify(dto.services);
    if (dto.images !== undefined) updateData.images = JSON.stringify(dto.images);
    if (dto.highlights !== undefined) updateData.highlights = dto.highlights;
    if (dto.technologies !== undefined) updateData.technologies = JSON.stringify(dto.technologies);
    // tags字段已移除，使用services字段存储标签信息
    if (dto.clientName !== undefined) updateData.clientName = dto.clientName;
    if (dto.completedAt !== undefined) updateData.completedAt = dto.completedAt;
    if (dto.location !== undefined) updateData.location = dto.location;
    if (dto.projectValue !== undefined) updateData.projectValue = dto.projectValue;
    if (dto.challenges !== undefined) updateData.challenges = dto.challenges;
    if (dto.solutions !== undefined) updateData.solutions = dto.solutions;
    // featured字段已从cases表中移除
    if (dto.status !== undefined) updateData.status = dto.status;
    if (dto.sort !== undefined) updateData.sort = dto.sort;

    return updateData;
  }
}

// 通用映射工具函数
export class MapperUtils {
  /**
   * 安全解析JSON字符串
   */
  static safeParseJSON<T>(jsonString: string | null, defaultValue: T): T {
    if (!jsonString) return defaultValue;
    try {
      return JSON.parse(jsonString);
    } catch {
      return defaultValue;
    }
  }

  /**
   * 安全序列化为JSON字符串
   */
  static safeStringifyJSON(data: any): string | null {
    if (data === undefined || data === null) return null;
    try {
      return JSON.stringify(data);
    } catch {
      return null;
    }
  }

  /**
   * 创建分页元数据
   */
  static createPaginationMeta(page: number, pageSize: number, total: number) {
    const totalPages = Math.ceil(total / pageSize);
    return {
      current: page,
      pageSize,
      total,
      totalPages
    };
  }

  /**
   * 创建统一API响应
   */
  static createApiResponse<T>(data: T, message?: string) {
    return {
      success: true,
      data,
      message,
      timestamp: new Date().toISOString()
    };
  }

  /**
   * 创建分页API响应
   */
  static createPaginatedResponse<T>(items: T[], page: number, pageSize: number, total: number, message?: string) {
    return {
      success: true,
      data: items,
      pagination: this.createPaginationMeta(page, pageSize, total),
      message,
      timestamp: new Date().toISOString()
    };
  }
}